<?php

namespace app\common\server;

class Rsa
{
    /**
     * private key
     */
    private $_privKey;

    /**
     * public key
     */
    private $_pubKey;

    /**
     * the keys saving path
     */
    private $_keyPath;

    public function __construct ($path)
    {
        if (empty($path) || !is_dir($path)) {
            throw new \Exception('Must set the keys save path');
        }
        //设置私钥
        $this->_keyPath = $path;
        $file = $this->_keyPath . DIRECTORY_SEPARATOR . 'rsa_private_key.pem';
        $prk = file_get_contents($file);
        $this->_privKey = openssl_pkey_get_private($prk);
        //设置公钥
        $file = $this->_keyPath . DIRECTORY_SEPARATOR . 'rsa_public_key.pem';
        $puk = file_get_contents($file);
        $this->_pubKey = openssl_pkey_get_public($puk);
    }



    /**
     * setup the private key
     */
    private function setupPrivKey ()
    {
        if (is_resource($this->_privKey)) {
            return true;
        }
        $file = $this->_keyPath . DIRECTORY_SEPARATOR . 'rsa_private_key.pem';
        $prk = file_get_contents($file);
        $this->_privKey = openssl_pkey_get_private($prk);
        return true;
    }

    /**
     * setup the public key
     */
    private function setupPubKey ()
    {
        if (is_resource($this->_pubKey)) {
            return true;
        }
        $file = $this->_keyPath . DIRECTORY_SEPARATOR . 'rsa_public_key.pem';
        $puk = file_get_contents($file);
        $this->_pubKey = openssl_pkey_get_public($puk);
        return true;
    }

    /**
     * @function 私钥加密
     * @param $data
     * @return string|null
     */
    public function privEncrypt ($data)
    {
        echo $encrypted.'<br/>';
        var_export($this->_privKey);
        die;
        if (!is_string($data)) {
            return null;
        }

        $r = openssl_private_encrypt($data, $encrypted, $this->_privKey);
        if ($r) {
            return base64_encode($encrypted);
        }
        return null;
    }

    /**
     * @function 私钥解密
     * @param $data
     * @return string|null
     */
    public function privDecrypt ($encrypted)
    {
        if (!is_string($encrypted)) {
            return null;
        }
        $encrypted = base64_decode($encrypted);
        $r = openssl_private_decrypt($encrypted, $decrypted, $this->_privKey);
        if ($r) {
            return $decrypted;
        }
        return null;
    }

    /**
     * @function 公钥加密
     * @param $data
     * @return string|null
     */
    public function pubEncrypt ($data)
    {
        if (!is_string($data)) {
            return null;
        }
        $r = openssl_public_encrypt($data, $encrypted, $this->_pubKey);
        if ($r) {
            return base64_encode($encrypted);
        }
        return null;
    }

    /**
     * @function 公钥解密
     * @param $data
     * @return string|null
     */
    public function pubDecrypt ($crypted)
    {
        if (!is_string($crypted)) {
            return null;
        }
        $crypted = base64_decode($crypted);

        $r = openssl_public_decrypt($crypted, $decrypted, $this->_pubKey);
        if ($r) {
            return $decrypted;
        }
        return null;
    }

    /**
     * @function 私钥加签
     * @param $data
     * @return string|null
     */
    public function sign ($data)
    {
        if (!is_string($data)) {
            return null;
        }
        openssl_sign($data, $sign, $this->_privKey);
        //base64编码
        $sign = base64_encode($sign);
        return $sign;
    }

    /**
     * @function 公钥验签
     * @param $data
     * @return string|null
     */
    public function verify($data, $sign){
        if (!is_string($data)) {
            return null;
        }
        $result = (bool)openssl_verify($data, base64_decode($sign), $this->_pubKey);
        return $result;
    }


    public function __destruct ()
    {
        empty($this->_privKey) ? '' : openssl_free_key($this->_privKey);
        empty($this->_pubKey) ? '' : openssl_free_key($this->_pubKey);
    }
}